/**
 * \file String.h
 * \brief String definition class
 * \author Edouard ROGE
 * \date 19 september 2010
 */

#ifndef _STRING_
#define _STRING_

#include "Core/Define/Define.h"

/**
 * \class String
 * \brief String base class, allocation and deallocation manage by the MEM::Manager
 */
class String
{
public:
	/**
	 * \fn String();
	 * Default constructor
	 */
	String();

	/**
	 * \fn String( const String & _str);
	 * \param _str the string to copy
	 * Copy constructor
	 */
	String( const String & _str);

	/**
	 * \fn String(char * s);
	 * \param s buffer of char to copy
	 * Constructor with param
	 */
	String(char * s);

	/**
	 * \fn String(const char * s);
	 * \param s array of char to copy
	 * Constructor with param
	 */
	String(const char * s);

	/**
	 * \fn String(char c);
	 * \param c char to copy
	 * Constructor with param
	 */
	String(char c);

	/**
	 * \fn ~String();
	 * Destructor
	 */
	~String();

	/**
	 * \fn void Reserve(uint32 _iSize);
	 * \param _iSize Size of the buffer
	 * Reserve the buffer of the String
	 */
	void Reserve(uint32 _iSize);

	/**
	 * \fn void Clear();
	 * Clear the buffer of the String
	 */
	void Clear();

	/**
	 * \fn uint32 GetLength() const;
	 * \return the length of the string (the final char '\\0' non included)
	 */
	uint32 GetLength() const;

	/**
	 * \fn String SubString(uint32 _iDeb) const;
	 * \param _iDeb index from where the substring begins
	 * \return the sub-string from the index _iDeb
	 */
	String SubString(uint32 _iDeb) const;

	/**
	 * \fn String SubString(uint32 _iDeb, uint32 _iFin) const;
	 * \param _iDeb index from where the substring begins
	 * \param _iFin index from where the substring ends
	 * \return the sub-string from the index _iDeb to _iFin
	 */
	String SubString(uint32 _iDeb, uint32 _iFin) const;

	/**
	 * \fn int FindFirst( const String & _subString, uint32 _firstIndex = 0 ) const;
	 * \param _subString the first occurrence to search
	 * \param _firstIndex index to begin the research
	 * \return the index where the substring begins, or if it's not found, return -1
	 */
	int FindFirst( const String & _subString, uint32 _firstIndex = 0 ) const;

	/**
	 * \fn int FindLast( const String & _subString ) const;
	 * \param _subString the last occurrence to search
	 * \return the index where the substring begins, or if it's not found, return -1
	 */
	int FindLast( const String & _subString ) const;

	/**
	 * \fn int FindFirst( char _c, uint32 _firstIndex = 0 ) const;
	 * \param _c the first occurrence to search
	 * \param _firstIndex index to begin the research
	 * \return the index where the char is, or if it's not found, return -1
	 */
	int FindFirst( char _c, uint32 _firstIndex = 0 ) const;

	/**
	 * \fn int FindLast( char _c ) const;
	 * \param _c the last occurrence to search
	 * \return the index where the char is, or if it's not found, return -1
	 */
	int FindLast( char _c ) const;

	/**
	 * \fn void Replace( char _cOldChar, char _cNewChar );
	 * \param _cOldChar char to replace
	 * \param _cNewChar the new char that replaces the old one
	 */
	void Replace( char _cOldChar, char _cNewChar );

	/**
	 * \fn void Trim();
	 * \brief erase all character as space, tabulation and return
	 */
	void Trim();

	/**
	 * \fn int32 ToInt() const;
	 * \return integer value of the string
	 * \brief convert the string value to an integer value
	 */
	int32 ToInt() const;

	/**
	 * \fn double ToDouble() const;
	 * \return decimal value of the string
	 * \brief convert the string value to a decimal value
	 */
	double ToDouble() const;

	/**
	 * \fn void Printf(const char * _fmt, ...);
	 * \param _fmt format
	 * \param ... optional parameters for the values to put in the string
	 * \brief Set the string with variadic arguments
	 */
	void Printf(const char * _fmt, ...);

	/**
	 * \fn char * GetData() const;
	 * \return the buffer of char
	 */
	char * GetData() const;

	/**
	 * \fn operator const char * () const;
	 * \return the buffer of char
	 * casting operator
	 */
	operator const char * () const;

	/**
	 * \fn String & operator+= (char c);
	 * \param c add the char to the string
	 * \return (*this)
	 */
	String & operator+= (char c);

	/**
	 * \fn String & operator+= (char * s);
	 * \param s add the buffer of char to the string
	 * \return (*this)
	 */
	String & operator+= (char * s);

	/**
	 * \fn String & operator+= (const char * s);
	 * \param s add the buffer of char to the string
	 * \return (*this)
	 */
	String & operator+= (const char * s);

	/**
	 * \fn String & operator+= (const String & str);
	 * \param str add the string str to the current string
	 * \return (*this)
	 */
	String & operator+= (const String & str);

	/**
	 * \fn String & operator= (char c);
	 * \param c set the char to the string
	 * \return (*this)
	 * delete and recreate the buffer
	 */
	String & operator= (char c);

	/**
	 * \fn String & operator= (char * s);
	 * \param s set the buffer of char to the string
	 * \return (*this)
	 * delete and recreate the buffer
	 */
	String & operator= (char * s);

	/**
	 * \fn String & operator= (const char *s);
	 * \param s set the buffer of char to the string
	 * \return (*this)
	 * delete and recreate the buffer
	 */
	String & operator= (const char * s);

	/**
	 * \fn String & operator= (const String & str);
	 * \param str replace the current string by this one
	 * \return (*this)
	 * delete and recreate the buffer
	 */
	String & operator= (const String & str);

	/**
	 * \fn char & operator[](uint32 i);
	 * \param i index of char to retrieve
	 * \return the char expected
	 */
	char & operator[](uint32 i);

	/**
	 * \fn char operator[](uint32 i) const;
	 * \param i index of char to retrieve
	 * \return the char expected
	 */
	char operator[](uint32 i) const;

	/**
	 * \fn friend String operator+ (const String & str, char c);
	 * \param str String
	 * \param c char
	 * \return new string with the 2 params concatenated
	 */
	friend String operator+ (const String & str, char c);

	/**
	 * \fn friend String operator+ (const String & str, char *s);
	 * \param str string1
	 * \param s string2
	 * \return new string with the 2 params concatenated
	 */
	friend String operator+ (const String & str, char * s);

	/**
	 * \fn friend String operator+ (const String & str, const char *s);
	 * \param str string1
	 * \param s string2
	 * \return new string with the 2 params concatenated
	 */
	friend String operator+ (const String & str, const char * s);

	/**
	 * \fn friend String operator+ (char c, const String & str);
	 * \param c char
	 * \param str string
	 * \return new string with the 2 params concatenated
	 */
	friend String operator+ (char c, const String & str);

	/**
	 * \fn friend String operator+ (char * s, const String & str);
	 * \param s string1
	 * \param str string2
	 * \return new string with the 2 params concatenated
	 */
	friend String operator+ (char * s, const String & str);

	/**
	 * \fn friend String operator+ (const char * s, const String & str);
	 * \param s string1
	 * \param str string2
	 * \return new string with the 2 params concatenated
	 */
	friend String operator+ (const char * s, const String & str);

	/**
	 * \fn friend String operator+ (const String & str1, const String & str2);
	 * \param str1 string1
	 * \param str2 string2
	 * \return new string with the 2 params concatenated
	 */
	friend String operator+ (const String & str1, const String & str2);

	/**
	 * \fn friend bool operator==(const String & str1, const String & str2);
	 * \param str1 first string to compare
	 * \param str2 first string to compare
	 * \return true if the two string are equals
	 * comparison operator
	 */
	friend bool operator==(const String & str1, const String & str2);

	/**
	 * \fn friend bool operator==(const String & str1, const char * str2);
	 * \param str1 first string to compare
	 * \param str2 first string to compare
	 * \return true if the two string are equals
	 * comparison operator
	 */
	friend bool operator==(const String & str1, const char * str2);

	/**
	 * \fn friend bool operator==(const char * str1, const String & str2);
	 * \param str1 first string to compare
	 * \param str2 first string to compare
	 * \return true if the two string are equals
	 * comparison operator
	 */
	friend bool operator==(const char * str1, const String & str2);

	/**
	 * \fn friend bool operator!=(const String & str1, const String & str2);
	 * \param str1 first string to compare
	 * \param str2 first string to compare
	 * \return true if the two string are non equals
	 * comparison operator
	 */
	friend bool operator!=(const String & str1, const String & str2);

	/**
	 * \fn friend bool operator!=(const String & str1, const char * str2);
	 * \param str1 first string to compare
	 * \param str2 first string to compare
	 * \return true if the two string are non equals
	 * comparison operator
	 */
	friend bool operator!=(const String & str1, const char * str2);

	/**
	 * \fn friend bool operator!=(const char * str1, const String & str2);
	 * \param str1 first string to compare
	 * \param str2 first string to compare
	 * \return true if the two string are non equals
	 * comparison operator
	 */
	friend bool operator!=(const char * str1, const String & str2);

private:
	/**
	 * \fn void Append(char c);
	 * \param c char to add to current string
	 * delete and recreate the buffer
	 */
	void Append(char c);

	/**
	 * \fn void Append(char *s);
	 * \param s buffer to add to current string
	 * delete and recreate the buffer
	 */
	void Append(char * s);

	/**
	 * \fn void Append(const char *s);
	 * \param s buffer to add to current string
	 * delete and recreate the buffer
	 */
	void Append(const char * s);

	/**
	 * \fn void Append(char c);
	 * \param c char to set to current string
	 * delete and recreate the buffer
	 */
	void Set(char c);

	/**
	 * \fn void Append(char *s);
	 * \param s buffer to set to current string
	 * delete and recreate the buffer
	 */
	void Set(char * s);

	/**
	 * \fn void Set(const char *s);
	 * \param s buffer to set to current string
	 * delete and recreate the buffer
	 */
	void Set(const char * s);

	/** Buffer containing the chars */
	char * m_Buffer;
};


#endif //_STRING_
